/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Cliente;

import javax.swing.JOptionPane;
import PaqDatos.*;
import Comunicaciones.*;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

/**
 *
 * @author careigma
 */
public class Cliente extends Thread {

	public void avisar(String cadenaAviso) {
		JOptionPane.showMessageDialog(clienteGUI, "Nueva notificacioón : " + cadenaAviso, "Aviso", JOptionPane.OK_OPTION);
	}

	void desconectar() {
		socketCom.enviar("desconectar");

		socketComAvisos.terminar();
		socketComAvisos = null;
	}
	protected SocketCom socketCom = null;
	protected SocketCom socketComAvisos = null;
	protected SocketConexion socketConexionAvisos = null;
	private ClienteGUI clienteGUI;
	private String nombreCliente;
	private XStream xstream;
	private int _puerto;

	public Cliente(ClienteGUI aClienteGui) {
		entrar("localhost", 4444, aClienteGui);
	};
    
    public void entrar(String nameServer, int puerto, ClienteGUI _clienteGui) {
		clienteGUI = _clienteGui;

		xstream = new XStream(new DomDriver());
		socketCom = new SocketCom(nameServer, puerto);
		_puerto = puerto;
	}

	public int login(String auser, char[] apassword) {
		socketCom.enviar(auser);
		socketCom.enviar(new String(apassword));

		String respuesta = socketCom.recibir();
		int login = Integer.parseInt(respuesta);

		if (!respuesta.equals("-1")) {
			respuesta = socketCom.recibir();

			nombreCliente = respuesta + "Cliente";

			socketConexionAvisos = new SocketConexion(_puerto + 1);
			socketComAvisos = socketConexionAvisos.aceptarConexion();
			start();
		}

		return login;
	}

	public String[] getAsignaturasMatriculadas() throws excepcion {
		InfoAsignatura[] asignaturasTotal;

		socketCom.enviar("getAsignaturas");

		String res = socketCom.recibir();
		Object generico = xstream.fromXML(res);

		if (generico instanceof excepcion) {
			throw (excepcion) generico;
		}

		asignaturasTotal = (InfoAsignatura[]) generico;

		String[] asignaturas = new String[asignaturasTotal.length];
		int j = 0;

		for (int i = 0; i < asignaturasTotal.length; i++) {
			if (asignaturasTotal[i].matriculado) {
				asignaturas[j] = asignaturasTotal[i].idAsignatura;
				j++;
			}
		}

		if (j == 0) {
			throw new excepcion("El usuario no está matriculado en ninguna asignatura");
		}

		String[] retorno = new String[j];
		System.arraycopy(asignaturas, 0, retorno, 0, j);

		return retorno;
	}

	public String[] getAsignaturas() {
		InfoAsignatura[] asignaturasTotal;

		try {

			socketCom.enviar("getAsignaturas");
			String res = socketCom.recibir();
			Object generico = xstream.fromXML(res);

			if (generico instanceof excepcion) {
				throw (excepcion) generico;
			}

			asignaturasTotal = (InfoAsignatura[]) generico;

		} catch (excepcion ex) {
			return new String[0];
		}
		String[] asignaturas = new String[asignaturasTotal.length];

		for (int i = 0; i < asignaturasTotal.length; i++) {
			asignaturas[i] = asignaturasTotal[i].idAsignatura;
		}

		return asignaturas;
	}

	public void matricular(String aIdAsignatura) throws PaqDatos.excepcion {
		socketCom.enviar("matricular");
		socketCom.enviar(aIdAsignatura);

		String res = socketCom.recibir();
		Object res2 = xstream.fromXML(res);

		if (res2 instanceof excepcion) {
			throw (excepcion) res2;
		}
	}

	public String[] getTemasAsignatura(String idAsig) throws PaqDatos.excepcion {
		socketCom.enviar("getTemasAsignatura");
		socketCom.enviar(idAsig);
		String res = socketCom.recibir();
		Object generico = xstream.fromXML(res);

		if (generico instanceof excepcion) {
			throw (excepcion) generico;
		}

		return (String[]) generico;
	}

	public void anyadirPregunta(String aIdAsig, String aIdTema, String aEnunciadoP) {
		socketCom.enviar("anyadirPregunta");
		socketCom.enviar(aIdAsig);
		socketCom.enviar(aIdTema);
		socketCom.enviar(aEnunciadoP);

		socketCom.recibir();
	}

	public void anyadirRespuesta(String aIdPregunta, String aEnunciadoR, boolean aEsCierta) throws excepcion {
		socketCom.enviar("anyadirRespuesta");
		socketCom.enviar(aIdPregunta);
		socketCom.enviar(aEnunciadoR);
		socketCom.enviar((aEsCierta) ? "true" : "false");

		String res = socketCom.recibir();
		Object generico = xstream.fromXML(res);

		if (generico instanceof excepcion) {
			throw (excepcion) generico;
		}
	}

	public String[] getExamenes() {
		try {
			//Devuelve un array con los ID de todos los exámenes de ese profesor
			socketCom.enviar("getExamenes");

			String res = socketCom.recibir();
			Object generico = xstream.fromXML(res);

			if (generico instanceof excepcion) {
				throw (excepcion) generico;
			}

			InfoExamen[] ie = (InfoExamen[]) generico;

			String[] ret = new String[ie.length];

			for (int i = 0; i < ie.length; i++) {
				ret[i] = ie[i].idExamen;
			}

			return ret;
		} catch (excepcion ex) {
			//no pasa nada si no hay examenes, simplemente no se muestra ninguno
			return new String[0];
		}
	}

	public PaqDatos.InfoExamen[] getNotasExamen(String idExamen) {
		socketCom.enviar("verNotasDelExamen");
		socketCom.enviar(idExamen);

		String res = socketCom.recibir();
		return (InfoExamen[]) xstream.fromXML(res);
	}

	public PaqDatos.InfoExamenEspecifico getInfoExamenEspecifico(String idAlumno, String idExamen) {
		socketCom.enviar("verExamenEspecificoAlumno");
		socketCom.enviar(idExamen);
		socketCom.enviar(idAlumno);
		return (InfoExamenEspecifico) xstream.fromXML(socketCom.recibir());
	}

	public void ponerExamen(String aIdAsignatura, PaqDatos.InfoTema[] aTemas, String aFechaIni, String aFechaFin) throws excepcion {
		socketCom.enviar("ponerExamen");
		socketCom.enviar(aIdAsignatura);
		socketCom.enviar(xstream.toXML(aTemas).replaceAll("\n", ""));
		socketCom.enviar(aFechaIni);
		socketCom.enviar(aFechaFin);

		String res = socketCom.recibir();
		Object generico = xstream.fromXML(res);

		if (generico instanceof excepcion) {
			throw (excepcion) generico;
		}
	}

	public PaqDatos.InfoExamen[] getExamenesAlumno() {
		try {

			socketCom.enviar("getExamenes");
			String res = socketCom.recibir();
			Object generico = xstream.fromXML(res);

			if (generico instanceof excepcion) {
				throw (excepcion) generico;
			}

			return (InfoExamen[]) generico;
		} catch (excepcion ex) {
			System.out.println(ex.msg);
		}

		return new InfoExamen[0];
	}

	public PaqDatos.InfoNotificacionExamen[] getNotificaciones() {
		socketCom.enviar("getNotificacionesExamen");
		return (InfoNotificacionExamen[]) xstream.fromXML(socketCom.recibir());

	}

	public PaqDatos.InfoExamenEspecifico generarExamen(String idExamen) throws PaqDatos.excepcion {

		socketCom.enviar("generarExamen");
		socketCom.enviar(idExamen);

		Object generico = xstream.fromXML(socketCom.recibir());

		if (generico instanceof excepcion) {
			throw (excepcion) generico;
		}

		return (InfoExamenEspecifico) generico;
	}

	public void enviarExamenEspecificoResulto(String idExamen, InfoExamenEspecifico ieeA) {

		socketCom.enviar("terminarExamen");
		socketCom.enviar(idExamen);
		socketCom.enviar(xstream.toXML(ieeA).replaceAll("\n", ""));

		socketCom.recibir();
	}

	public PaqDatos.InfoExamenEspecifico getInfoExamenEspecificoAlumno(String idExamen) {
		socketCom.enviar("verExamenEspecifico");
		socketCom.enviar(idExamen);
		return (InfoExamenEspecifico) xstream.fromXML(socketCom.recibir());
	}

	public void setNoficacionLeida(String idNotificacion) {

		socketCom.enviar("setNoficacionLeida");
		socketCom.enviar(idNotificacion);
		socketCom.recibir();
	}

	@Override
	public void run() {
		while (true) {
			if (socketComAvisos != null) {
				String peticion = socketComAvisos.recibir();

				if (peticion == null) {
					continue;
				}

				if (peticion.equals("avisar")) {
					avisar(socketComAvisos.recibir());
				}
			} else {
				break;
			}
		}
	}
}
